<?php
namespace src;
use classlib\input;
use classlib\logger;
use classlib\request;
use src\logic\Cadmin;
use classlib\core as C;
use classlib\core\lang;
use classlib\core\router;
use classlib\core\controller;
use src\logic\workflow\doc_executor;
class Cexecutor extends controller {
	public function main() {
		$view       = C\view::inst('extjs');
		$ousrid     = Cadmin::islogin($view);
		$executorid = (int)input::get('id');
		$workflowid = (int)input::get(0);
		$executor   = new doc_executor($executorid, $workflowid);
		try {
			$executor->__init__($ousrid);
		} catch (\Exception $e) {
			$view->assign_error($e->getCode(), $e->getMessage());
		}
		$view->assign_by_ref('executor', $executor);
		$view->display('workflow/executor.ext.js');
	}
	
	//处理业务抄送的业务逻辑
	public function doccsender() {
		$data = input::args();
		logger::inst()->write(serialize($data));
	}
	
	//终止执行的任务
	public function dostop() {
		$view       = C\view::inst('json');
		$ousrid     = Cadmin::islogin($view);
		$lang       = C\lang::inst('adm');
		$executorid = (int)input::post('executorid');
		$remark     = input::post('remark');
		if ($executorid < 1 || empty($remark)) {
			$view->assign_error('50006', $lang->get('workflow', '50006'));
		}
		$eorm = C\model::load('main.proc.execution');
		$item = $eorm->get_one($executorid);
		if (empty($item) || $item['applyuserid'] != $ousrid) {
			$view->assign_error('50007', $lang->get('workflow', '50007'));
		}
		//流程已经结束或者终止，则不能再次执行
		if ($item['status'] == doc_executor::ENDSUB || $item['status'] == doc_executor::TERMINATE) {
			$view->assign_error('50008', $lang->get('workflow', '50008'));
		}
		$remarks = $item['remark'].'['.$remark.']';
		$data    = array('stopuserid'=>$ousrid, 'stopusername'=>doc_executor::disname($ousrid),
				'status'=>doc_executor::TERMINATE, 'stoptime'=>C\config::$nowtime, 'remark'=>$remarks);
		$eorm->save($executorid, $data);
		//终止该节点的子流程 递归遍历
		$i    = 0; //统计处理的子流程的数量
		$eids = array($executorid);
		while (true) {
			$where   = array();
			$where[] = array('pid', $eids, \classlib\orm::OP_IN);
			$items   = $eorm->get_list(0, -1, $where);
			if (count($items) < 1) {
				break;
			}
			$eids    = array();
			foreach ($items as $item) {
				$eids[] 		= $item['id'];
				$remarks 		= $item['remark'].'['.$remark.']';
				$data['remark'] = $remarks;
				$eorm->save($item['id'], $data);
				$i++;
			}
		}
		$msg = $lang->get('workflow', '50009');
		$view->assign('msg', sprintf($msg, $i));
		$view->display();
	}
	
	//用户接受任务
	public function doaccept() {
		$view    = C\view::inst('json');
		$ousrid  = Cadmin::islogin($view);
		$stateid = (int)input::post('sid');
		$lang    = C\lang::inst('adm');
		$state   = C\model::load('main.proc.nodestate')->get_one($stateid);
		if (empty($state) || $state['status'] != 0) {
			$view->assign_error('1', $lang->get('workflow', '50030'));
		}
		$workflow = C\model::load('main.proc.workflow')->get_one($state['workflowid']);
		$node  = C\model::load('main.proc.node')->get_one($state['nodeid']);
		$docer = new $workflow['clasz'];
		$flag  = $docer->isaccpetable($ousrid, $node['roleid'], $state);
		if (!$flag) {
			$view->assign_error('2', $lang->get('workflow', '50031'));	
		}
		$expire = $state['expire'] + C\config::$nowtime - $state['createtime'];
		$fields = array('accepttime'=>C\config::$nowtime, 'acceptuserid'=>$ousrid,
			'acceptusername'=>doc_executor::disname($ousrid), 'expire'=>$expire, 'status'=>'1');
		C\model::load('main.proc.nodestate')->save($stateid, $fields);
		$view->assign('msg', $lang->get('workflow', '50032'));
		$view->display();
	}
	
	//任务转单
	public function dodeliver() {
		$view  = C\view::inst('json');
		$ousrid= Cadmin::islogin($view);
		$lang  = C\lang::inst('adm');
		$sid   = (int)input::get_post('sid');
		$userid= (int)input::get_post('userid');
		$sorm  = C\model::load('main.proc.nodestate');
		$state = $sorm->get_one($sid);
		if (empty($state) || $state['status'] != 1) {
			$view->assign_error('1', $lang->get('workflow', '50006'));
		}
		if ($state['acceptuserid'] != $ousrid) {
			$view->assign_error('3', $lang->get('workflow', '50033'));
		}
		$user  = C\model::load('main.sys.user')->get_one($userid);
		if (empty($user) || $user['status'] != 1) {
			$view->assign_error('4', $lang->get('workflow', '50034'));
		}
		$disname = doc_executor::disname($userid);
		$deliver = $state['acceptusername'].'->'.$disname.';';
		$fields  = array('acceptuserid'=>$userid, 'acceptusername'=>$disname, 'deliverinfo'=>$deliver);
		$sorm->save($sid, $fields);
		$view->assign('msg', $lang->get('workflow', '50035'));
		$view->display();
	}
	
	//节点提交处理
	public function dosubmit() {
		$view  	   = C\view::inst('json');
		$ousrid	   = Cadmin::islogin($view);
		$lang      = C\lang::inst('adm');
		$workflowid= (int)input::post('workflowid');
		if ($workflowid < 0) {
			$view->assign_error('1', $lang->get('workflow', '50006'));
		}
		$worm      = C\model::load('main.proc.workflow');
		$workflow  = $worm->get_one($workflowid);
		if (empty($workflow) || $workflow['status'] != 1) {
			$view->assign_error('2', $lang->get('workflow', '50036'));
		}
		$status    = (int)input::post('status');
		$dlang     = lang::inst('dd');
		if (!$dlang->get('wk00002', $status)) {
			$view->assign_error('3', $lang->get('workflow', '50006'));
		}
		//创建一个执行执行实例，同时追加首个节点
		$docer = new $workflow['clasz'];
		$executorid= (int)input::post('executorid');
		if ($executorid < 1) {
			$executorid = $docer->create($workflow, $ousrid);
		}
		//处理业务的当前节点编号
		$nodeid    = (int)input::get_post('nodeid');
		$sorm      = C\model::load('main.proc.nodestate');
		$where     = array('workflowid'=>$workflowid, 'executionid'=>$executorid, 'nodeid'=>$nodeid);
		$state     = $sorm->get_item($where);
		if (!$state || $state['status'] != 1 || $state['acceptuserid'] != $ousrid) {
			$view->assign_error('4', $lang->get('workflow', '50006'));
		}
		//工作流执行实例状态
		$executor = C\model::load('main.proc.execution')->get_one($executorid);
		if (empty($executor) || $executor['status'] != 1) {
			$view->assign_error('5', $lang->get('workflow', '50006'));
		}
		$state['status'] = $status;
		$node     = C\model::load('main.proc.node')->get_one($state['nodeid']);
		$result   = $docer->{$node['actions']}($state);//执行业务方法
		if (!is_scalar($result)) {
			$view->assign_error('6', $lang->get('workflow', '50037'));
		}
		$state['result'] = strval($result);
		$json     = input::args();
		$state['json']        = json_encode($json);
		$state['ccreceivers'] = input::post('ccreceivers');
		//抄送http消息提醒 通知
		$taskurl  = C\router::get_url('admin-workflow-executor', '', array('id'=>$executorid));
		$disname  = doc_executor::disname($ousrid);
		if ($state['ccreceivers'] && $workflow['ccapi']) {
			$msg  = $lang->get('workflow', '50038');
			$msg  = sprintf($msg, $disname, $workflow['name'], $executorid, $taskurl, $taskurl);
			$query= json_encode(array('cc'=>$state['ccreceivers'], 'msg'=>$msg));
			$state['ccsender'] = \classlib\request::curl($workflow['ccapi'], $query);
		}
		$remark  = input::get_post('remark');
		if($remark && $remark != $state['remark']) {//改动的话重新复制
			$state['remark']   = $remark;
		}
		$state['remark']      .= in_array($status, doc_executor::$nextpass)? '[Pass]':'[Reject]';
		$state['completetime'] = C\config::$nowtime;
		//工作指派节点
		$acceptuid = (int)input::post('acceptuid');
		if ($acceptuid > 0) {
			$state['acceptuid'] = $acceptuid;
		}
		$sorm->save($state['id'], $state);
		//审批通过的情况节点信息解锁
		if (in_array($status, doc_executor::$nextpass)) {//驱动下一个节点
			if(doc_executor::EXEC_COMPLETE == $docer->nextnode($state)) {
				$sdata = array('status'=>doc_executor::EXEC_COMPLETE, 'etime'=>C\config::$nowtime);
				C\model::load('main.proc.execution')->save($executorid, $sdata);
			} 
		}
		if (in_array($status, doc_executor::$nextreject)) {//拒绝审批 返回前一个节点
			$docer->backnode($state);
		}
		$view->assign_by_ref('url', $taskurl);
		$view->assign('msg', $lang->get('workflow', '50039'));
		$view->display();
	}
}